package com.runjian.demo.base;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @Description
 * @Author HHJ
 * @Date 2025-04-17 21:34
 */
@Data
public class Result<T> {
    private Integer code;
    private String msg;
    private T data;

    @JsonInclude(JsonInclude.Include.NON_NULL)
    private Long total;

    private Result() {
    }

    @JsonCreator
    private Result(@JsonProperty("code") Integer code, @JsonProperty("data") T rows, @JsonProperty("total") Long total, @JsonProperty("msg") String message) {
        this.code = code;
        this.total = total;
        this.data = rows;
        this.msg = message;
    }

    public static <T> Result<T> page() {
        return new Result(BusinessEnums.SUCCESS.getCode(), new ArrayList(), 0L, BusinessEnums.SUCCESS.getMessage());
    }


    public static <T> Result<T> page(IPage<T> page) {
        List<T> list = page.getRecords();
        return new Result(BusinessEnums.SUCCESS.getCode(), list, page.getTotal(), BusinessEnums.SUCCESS.getMessage());
    }

    public static <T> Result<List<T>> page(IPage page, Class<T> targetType) {
        List records = page.getRecords();
        if (CollUtil.isEmpty(records)) {
            return new Result(BusinessEnums.SUCCESS.getCode(), new ArrayList(), 0L, BusinessEnums.SUCCESS.getMessage());
        }
        List<T> list = new ArrayList<>(records.size());
        for (Object record : records) {
            T o = (T) BeanUtil.copyProperties(record, targetType);
            list.add(o);
        }
        return new Result(BusinessEnums.SUCCESS.getCode(), list, page.getTotal(), BusinessEnums.SUCCESS.getMessage());
    }


    public static <T> Result<T> error(String message) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMsg(message);
        result.setData(null);
        return result;
    }

    public static Result<?> fail(Integer i, String message) {
        Result<?> result = new Result<>();
        result.setCode(Objects.nonNull(i) ? i : 500);
        result.setMsg(message);
        result.setData(null);
        return result;
    }

    public static <TT> Result success(TT d) {
        Result<TT> result = new Result<>();
        result.setCode(200);
        result.setData(d);
        result.setMsg("ok");
        return result;
    }
}
